/*
 * Copyright 2010 Kevin L'Huillier <klhuillier@gmail.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.lhuillier.pwsafe.model;


import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


/**
 * Database-wide preferences.
 * <p>
 * This would normally also hold Application-wide preferences, but because
 * our applications will differ from Password Safe's, and we can implement
 * these however we wish, we only use this class for DB preferences.
 */
public class Preferences {
    private final Map<Integer, Boolean> boolValues;
    private final Map<Integer, Integer> intValues;
    private final Map<Integer, String> strValues;

    public Preferences() {
        boolValues = new HashMap<Integer, Boolean>();
        intValues = new HashMap<Integer, Integer>();
        strValues = new HashMap<Integer, String>();
    }

    public Boolean getBoolean(BooleanPrefType prefType) {
        return getBoolean(prefType.ordinal());
    }

    public Boolean getBoolean(int id) {
        Boolean result = boolValues.get(id);
        if (result == null) {
            return defaultBoolean(id);
        }
        return result;
    }

    public void setBoolean(BooleanPrefType prefType, Boolean value) {
        setBoolean(prefType.ordinal(), value);
    }

    public void setBoolean(int id, Boolean value) {
        if (value == null || value.equals(defaultBoolean(id))) {
            boolValues.remove(id);
        } else {
            boolValues.put(id, value);
        }
    }

    Boolean defaultBoolean(int id) {
        BooleanPrefType type = BooleanPrefType.forId(id);
        return type == null ? null : type.getDefaultValue();
    }

    public Integer getInteger(IntegerPrefType prefType) {
        return getInteger(prefType.ordinal());
    }

    public Integer getInteger(int id) {
        Integer result = intValues.get(id);
        if (result == null) {
            return defaultInteger(id);
        }
        return result;
    }

    public void setInteger(IntegerPrefType prefType, Integer value) {
        setInteger(prefType.ordinal(), value);
    }

    public void setInteger(int id, Integer value) {
        if (value == null || value.equals(defaultInteger(id))) {
            intValues.remove(id);
        } else {
            intValues.put(id, value);
        }
    }

    Integer defaultInteger(int id) {
        IntegerPrefType type = IntegerPrefType.forId(id);
        return type == null ? null : type.getDefaultValue();
    }

    public String getString(StringPrefType prefType) {
        return getString(prefType.ordinal());
    }

    public String getString(int id) {
        String result = strValues.get(id);
        if (result == null) {
            return defaultString(id);
        }
        return result;
    }

    public void setString(StringPrefType prefType, String value) {
        setString(prefType.ordinal(), value);
    }

    public void setString(int id, String value) {
        if (value == null || value.equals(defaultString(id))) {
            strValues.remove(id);
        } else {
            strValues.put(id, value);
        }
    }

    String defaultString(int id) {
        StringPrefType type = StringPrefType.forId(id);
        return type == null ? null : type.getDefaultValue();
    }

    public Map<Integer, Boolean> nonDefaultBooleans() {
        return Collections.unmodifiableMap(boolValues);
    }

    public Map<Integer, Integer> nonDefaultIntegers() {
        return Collections.unmodifiableMap(intValues);
    }

    public Map<Integer, String> nonDefaultStrings() {
        return Collections.unmodifiableMap(strValues);
    }

    // TODO: Implement or delete
    public RecordPwPolicy getPasswordPolicy() {
        return null;
    }
}
